﻿using System;
using System.Text;
using System.Net;
using System.IO;
using System.Threading;
using System.Drawing;

using StProxyHelper.Entity;

namespace StProxyHelper
{
    public class HttpHelper
    {
        #region 变量
        private int currentTry = 0;
        private int connectTimeOutRetryTryMaxTimes = 3;
        ProxyHost proxyHost = null;
        #endregion

        #region 构造函数
        public HttpHelper()
        { 
            
        }

        public HttpHelper(ProxyHost proxyHost)
        {
            this.proxyHost = proxyHost;
        }
        #endregion

        private HtmlDocument GetHtml(string url,Entity.ProxyHost proxyHost)
        {
            HtmlDocument result = new HtmlDocument();

            HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
            HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();

            try
            {         
                if (proxyHost != null)
                {
                    if (!proxyHost.Address.Equals(""))
                    {
                        IWebProxy webProxy = new WebProxy(proxyHost.Address);
                        httpWebRequest.Proxy = webProxy;
                    }
                    else if (!proxyHost.Host.Equals("") && proxyHost.Port > 0)
                    {
                        WebProxy webProxy = new WebProxy(proxyHost.Host, proxyHost.Port);
                        httpWebRequest.Proxy = webProxy;
                    }
                }

                using (Stream stream = httpWebResponse.GetResponseStream())
                {
                    result.ContentLength = httpWebResponse.ContentLength;

                    if (result.ContentEncoding == null)
                    {
                        result.ContentEncoding = Encoding.Default;
                    }
                    else
                    {
                        result.ContentEncoding = Encoding.GetEncoding(httpWebRequest.TransferEncoding);
                    }

                    //创建文件流对象
                    int length = 10240;
                    byte[] buffer = new byte[10250];
                    int byteSread = 0;

                    while ((byteSread = stream.Read(buffer, 0, length)) > 0)
                    {
                        //把数据写入文件
                        result.DocumentText += result.ContentEncoding.GetString(buffer, 0, byteSread);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return result;
        }

        #region 公共方法
        /// <summary>
        /// 获取指定页面的HTML代码
        /// </summary>
        /// <param name="url">指定页面的路径</param>
        /// <param name="postData">回发的数据</param>
        /// <param name="isPost">是否以post方式发送请求</param>
        /// <param name="cookieCollection">Cookie集合</param>
        /// <returns></returns>
        public string GetHtml(
            string url, 
            string postData, 
            bool isPost, 
            HttpRequest httpRequest)
        {
            if (string.IsNullOrEmpty(postData))
            {
                return GetHtml(url, httpRequest);
            }

            currentTry++;

            try
            {
                byte[] byteRequest = Encoding.Default.GetBytes(postData);

                HttpWebRequest httpWebRequest;
                httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
                httpWebRequest.CookieContainer = httpRequest.CookieContainer;
                httpWebRequest.ContentType = httpRequest.ContentType;
                httpWebRequest.Referer = url;
                httpWebRequest.Accept = httpRequest.Accept;
                httpWebRequest.UserAgent = httpRequest.UserAgent;
                httpWebRequest.Method = isPost ? "POST" : "GET";
                httpWebRequest.ContentLength = byteRequest.Length;

                if (this.proxyHost != null)
                {
                    if (!this.proxyHost.Address.Equals(""))
                    {
                        IWebProxy webProxy = new WebProxy(this.proxyHost.Address);
                        httpWebRequest.Proxy = webProxy;
                    }
                    else if (!this.proxyHost.Host.Equals("") && this.proxyHost.Port > 0)
                    {
                        IWebProxy webProxy = new WebProxy(this.proxyHost.Host, this.proxyHost.Port);
                        httpWebRequest.Proxy = webProxy;
                    }
                }

                Stream stream = httpWebRequest.GetRequestStream();
                stream.Write(byteRequest, 0, byteRequest.Length);
                stream.Close();

                HttpWebResponse httpWebResponse;
                httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
                Stream responseStream = httpWebResponse.GetResponseStream();
                StreamReader streamReader = new StreamReader(responseStream, httpRequest.Encoding);
                string html = streamReader.ReadToEnd();
                streamReader.Close();
                responseStream.Close();

                currentTry = 0;
                return html;


            }
            catch (Exception ex)
            {
                if (currentTry <= connectTimeOutRetryTryMaxTimes)
                {
                    GetHtml(url, postData, isPost, httpRequest);
                }

                Console.WriteLine(ex.Message);
                //ExceptionHelper.Record("请求服务器超时：" + e.Message);

                currentTry = 0;
                return string.Empty;
            }
        }

        /// <summary>
        /// 获取指定页面的HTML代码
        /// </summary>
        /// <param name="url">指定页面的路径</param>
        /// <param name="HttpRequest">HttpRequest/param>
        /// <returns></returns>
        public string GetHtml(string url, HttpRequest httpRequest)
        {
            currentTry++;

            try
            {
                HttpWebRequest httpWebRequest;
                httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
                httpWebRequest.CookieContainer = httpRequest.CookieContainer;
                httpWebRequest.ContentType = httpRequest.ContentType;
                httpWebRequest.Referer = url;
                httpWebRequest.Accept = httpRequest.Accept;
                httpWebRequest.UserAgent = httpRequest.UserAgent;
                httpWebRequest.Method = "GET";

                if (this.proxyHost != null)
                {
                    if (!this.proxyHost.Address.Equals(""))
                    {
                        IWebProxy webProxy = new WebProxy(this.proxyHost.Address);
                        httpWebRequest.Proxy = webProxy;
                    }
                    else if (!this.proxyHost.Host.Equals("") && this.proxyHost.Port > 0)
                    {
                        IWebProxy webProxy = new WebProxy(this.proxyHost.Host, this.proxyHost.Port);
                        httpWebRequest.Proxy = webProxy;
                    }
                }

                HttpWebResponse httpWebResponse;
                httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
                Stream responseStream = httpWebResponse.GetResponseStream();
                StreamReader streamReader = new StreamReader(responseStream, httpRequest.Encoding);
                string html = streamReader.ReadToEnd();
                streamReader.Close();
                responseStream.Close();

                currentTry = 0;
                return html;
            }
            catch (Exception ex)
            {
                if (currentTry <= connectTimeOutRetryTryMaxTimes)
                {
                    GetHtml(url, httpRequest);
                }

                Console.WriteLine(ex.Message);

                currentTry = 0;
                return string.Empty;
            }
        }

        /// <summary>
        /// 获取指定页面的HTML代码
        /// </summary>
        /// <param name="url">指定页面的路径</param>
        /// <returns></returns>
        public string GetHtml(string url)
        {
            HttpRequest httpRequest = new HttpRequest();
            return GetHtml(url, httpRequest);
        }

        /// <summary>
        /// 获取指定页面的HTML代码
        /// </summary>
        /// <param name="url">指定页面的路径</param>
        /// <param name="postData">回发的数据</param>
        /// <param name="isPost">是否以post方式发送请求</param>
        /// <returns></returns>
        public string GetHtml(string url, string postData, bool isPost)
        {
            HttpRequest httpRequest = new HttpRequest();
            return GetHtml(url, postData, isPost, httpRequest);
        }

        /// <summary>
        /// 获取一个随机延迟
        /// </summary>
        /// <returns></returns>
        private int GetDynamicDelay()
        {
            return 0;
            //return new Random(DateTime.Now.Millisecond).Next(2000);
        }

        public Bitmap GetImage(string url)
        {
            HttpRequest httpRequest = new HttpRequest();
            return GetImage(url, httpRequest);
        }

        public Bitmap GetImage(string url, HttpRequest httpRequest)
        {
            currentTry++;

            try
            {
                HttpWebRequest httpWebRequest;
                httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
                httpWebRequest.CookieContainer = httpRequest.CookieContainer;
                httpWebRequest.Method = "GET";

                if (this.proxyHost != null)
                {
                    if (!this.proxyHost.Address.Equals(""))
                    {
                        IWebProxy webProxy = new WebProxy(this.proxyHost.Address);
                        httpWebRequest.Proxy = webProxy;
                    }
                    else if (!this.proxyHost.Host.Equals("") && this.proxyHost.Port > 0)
                    {
                        IWebProxy webProxy = new WebProxy(this.proxyHost.Host, this.proxyHost.Port);
                        httpWebRequest.Proxy = webProxy;
                    }
                }

                HttpWebResponse httpWebResponse;
                httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
                Stream responseStream = httpWebResponse.GetResponseStream();

                Bitmap bitmap = new Bitmap(responseStream);

                responseStream.Close();

                currentTry = 0;
                return bitmap;
            }
            catch (Exception ex)
            {
                if (currentTry <= connectTimeOutRetryTryMaxTimes)
                {
                    GetHtml(url, httpRequest);
                }

                Console.WriteLine(ex.Message);

                currentTry = 0;
                return null;
            }
        }

        #endregion
    }
}
